/**
 * @author o modificaciones Angel Marcos Sosa León o
 */
package uoc.ei.practica;

import uoc.ei.tads.Diccionario;
import uoc.ei.tads.DiccionarioAVLImpl;
import uoc.ei.tads.DiccionarioVectorImpl;
import uoc.ei.tads.Iterador;
import uoc.ei.tads.IteradorVectorImpl;
import uoc.ei.tads.TablaDispersion;


/**
 * clase que representa un campeonato
 */
public class ChampionShip extends IdentifiedObject {
	/**
	 * lista de partidas asociadas a un campeonato
	 */
	private Diccionario<String, Game> games;
	
	/**
	 * lista de palabras asociadas a un campeonato
	 */
	private Diccionario<String, Word> words;
	/**
	 * AVL de Jugadores inscritos en el campeonato 
	 */

	private Diccionario<String, Player> playersRegistered; 
	
	/**
	 * Vector ordenado con las clasificaciones de los jugadores
	 */
	private Diccionario<String, Player> clasificacion; 
	
	

	/**
	 * palabras de un campeonato
	 */
	private static Letter[] letters;
	
	/**
	 * apuntador para gestionar las palabras de un campeonato
	 */
	private static int pLetters; 
	/**
	 * Indicador de si el campeonato acepta inscripciones o no
	 */
	private boolean abierto;
	/**
	 * Numero inscripciones del campeonato para dimensionar el Vector
	 * clasificaciones
	 */
	private int numeroInscripciones;
	



	
	public ChampionShip(String championShipId) {
		super(championShipId);
		this.games=new DiccionarioAVLImpl<String, Game>();
		this.words=new TablaDispersion<String, Word>();
		this.playersRegistered= new DiccionarioAVLImpl<String, Player>();
		this.letters=new Letter[ScrabbleManager.MAX_LETTERS];
		this.pLetters=0;
		this.abierto=true;
		// 
		
		
	}
	
	
	/**
	 * método para añadir una partida a un campeonato
	 * @param gameId identificador del campeonato
	 * @param player1 primer jugador
	 * @param player2 segundo jugador
	 * @throws EIException lanza una excepción en el caso que la partida ya exista
	 */
	public void addGame(String gameId, String player1, String player2) throws EIException {
		this.games.insertar(gameId, new Game(this, gameId, player1, player2));
	}
	
	/**
	 * método para añadir un jugador al vector de clasificaciones	 * 
	 * @param player p Jugador a añadir
	 * @throws EIException 
	 */
	
	public void addPlayerToClasificacion(Player p) throws EIException {
		
		String puntos=p.getPuntos()+"";		
		this.clasificacion.insertar(puntos, p);
	}
	/**
	 * método que añade una palabra al campeonato
	 * @param word paraula a añadir
	 * @throws EIException lanza una excepción en el caso que la palabra ya exista.
	 */
	public void addWord(String word) throws EIException {		
		
		Word w = this.words.consultar(word);
		if (w==null) {
			w=new Word(word);
			this.words.insertar(word, w);
		}
		else throw new EIException(Messages.WORD_ALREADY_EXISTS);
		
	}

	/**
	 * método que añade una letra asociada a un campeonato
	 * @param letter letra a añadir
	 * @param points puntos
	 * @param total número de letras
	 * @throws EIException lanza una excepción en el caso que la letra
	 * ya exista o que supere el máximo de letras.
	 */
	public void addLetter(String letter, int points, int total)
			throws EIException {
		
		Letter l = getLetter(letter);
		if (l!=null) throw new EIException(Messages.LETTER_ALREADY_EXISTS); 
		else 
			if (pLetters<ScrabbleManager.MAX_LETTERS) this.letters[pLetters++]=new Letter(letter, points, total);
			else throw new EIException(Messages.MAX_LETTERS);
			
	}


	
	public Iterador<Word> words() { 
		return this.words.elementos();
	}


	public Game findGame(String gameId) throws EIException {
		Game gAux;
		boolean found = false;		
		gAux = games.consultar(gameId);
		if(gAux!=null)
			found = true;
		
		return  found ? gAux : null;	
	}
	
	
	public Iterador<Letter> letters() throws EIException {
		if (this.pLetters==0) throw new EIException(Messages.NO_LETTERS);
		
		Iterador<Letter> it =  new IteradorVectorImpl(this.letters,this.pLetters,0);
		return it;
		
	}

	
	public Letter getLetter(String letter) {
		int i=0;
		Letter l = null;
		boolean found=false;
		
		while (i< pLetters && !found) {
			l = letters[i];
			found = l.is(letter);
			i++;
		}
		
		return (found?l:null);
	}


	public boolean isAbierto() {
		return abierto;
	}


	public void CerrarInscripcion() {
		this.abierto = false;
		this.clasificacion = new DiccionarioVectorImpl<String, Player>(numeroInscripciones);
	}
	
	public Iterador<Player> playersRegistered() throws EIException {
		if (playersRegistered.estaVacio())
			throw new EIException(Messages.NO_PLAYERS);

		return  playersRegistered.elementos();
		
	}
	
	public Iterador<Player> clasificacion() throws EIException {
		if (clasificacion.estaVacio())
			throw new EIException(Messages.NO_PLAYERS);

		return  clasificacion.elementos();
		
	}
	
	public Iterador<Game> games() throws EIException {
		if (games.estaVacio())
			throw new EIException(Messages.NO_GAMES);

		return  games.elementos();
		
	}
	
	public Player findPlayerregisterd(String nif) {
		
		Player pAux;
		boolean found = false;		
		pAux = playersRegistered.consultar(nif);
		if(pAux!=null)
			found = true;
		
		return  found ? pAux : null;	      
	}
	
	public void addOrRemovePlayerRegisterd(Player p) throws EIException {	
		if(findPlayerregisterd(p.getNif()) == null)
		{
			
			playersRegistered.insertar(p.getNif(), p);			
		}		
		else playersRegistered.borrar(p.getNif());
		
}
public Word findWords(String word) {
		
		Word wAux;
		boolean found = false;		
		wAux = words.consultar(word);
		if(wAux!=null)
			found = true;
		
		return  found ? wAux : null;	      
	}


public int getNumeroInscripciones() {
	return numeroInscripciones;
}


public void setNumeroInscripciones(int numeroInscripciones) {
	this.numeroInscripciones = numeroInscripciones;
}
		
}
